const { expect, use } = require('chai');
const { BigNumber } = require('ethers');
const { deployContract, MockProvider, solidity } = require('ethereum-waffle');
const { ethers, upgrades } = require("hardhat");

use(solidity);

describe("Test NFTSwap.sell Interface", function () {
    var ERC20;
    var ERC721;
    var ERC1155;
    var OWNER;
    var ADDR1;

    beforeEach(async () => {
        [OWNER, ADDR1] = await ethers.getSigners();

        const ERC20PresetMinterPauser = await ethers.getContractFactory("ERC20PresetMinterPauser", OWNER);
        ERC20 = await ERC20PresetMinterPauser.deploy("TestERC20", "T20");

        const ERC721PresetMinterPauserAutoId = await ethers.getContractFactory("ERC721PresetMinterPauserAutoId", OWNER);
        ERC721 = await ERC721PresetMinterPauserAutoId.deploy("TestERC721", "T721", "https://t721.com");

        const ERC1155PresetMinterPauser = await ethers.getContractFactory("ERC1155PresetMinterPauser", OWNER);
        ERC1155 = await ERC1155PresetMinterPauser.deploy("https://t1155.com");
    });


    it("Should be sale an ERC721 token successful", async function () {
        // 实例化 NFTSwap合约
        const NFTSwap = await ethers.getContractFactory("NFTSwap");
        const nftSwap = await upgrades.deployProxy(NFTSwap, ["0x8006C00F6217dE69f7F6630EEc377819CE68e37f", 1000000, 0, ERC20.address], {
            initializer: '__NFTSwap_init'
        });
        await nftSwap.deployed();

        // 实例化ERC721 合约
        await ERC721.deployed();

        // 增发 id=0 的token，并approve 给 NFTSwap
        var mintERC721Tx = await ERC721.connect(OWNER).mint(OWNER.address);
        await mintERC721Tx.wait();
        var approveERC721Tx = await ERC721.connect(OWNER).setApprovalForAll(nftSwap.address, true);
        await approveERC721Tx.wait();
        // 增发ERC20，并approve 给 NFTSwap
        var mintERC20TxO = await ERC20.connect(OWNER).mint(OWNER.address, BigNumber.from(1000000));
        await mintERC20TxO.wait();
        var approveERC20Tx = await ERC20.connect(OWNER).approve(nftSwap.address, BigNumber.from(1000000));
        await approveERC20Tx.wait();

        // 定义assets, assetType.ERC721 = 1
        var assets = [{ Contract: ERC721.address, TokenId: BigNumber.from(0), TokenValue: BigNumber.from(1), Type: 1 }]
        // 发起交易
        const sellTx = await nftSwap.sell(assets, 1, "0x0000000000000000000000000000000000000000", BigNumber.from(2000000));
        await sellTx.wait();
        // 获取交易结果
        var receipt = await ethers.provider.getTransactionReceipt(sellTx.hash);
        // 判断交易最终状态，必须为1
        expect(receipt.status).to.equal(1);
    });

    it("Should be sale an ERC1155 token successful", async function () {
        // 实例化 NFTSwap合约
        const NFTSwap = await ethers.getContractFactory("NFTSwap");
        const nftSwap = await upgrades.deployProxy(NFTSwap, ["0x8006C00F6217dE69f7F6630EEc377819CE68e37f", 1000000, 0, ERC20.address], { initializer: '__NFTSwap_init' });
        await nftSwap.deployed();

        // 实例化ERC1155 合约
        await ERC1155.deployed();

        // 增发 id=0 的token，并approve 给 NFTSwap
        var mintERC1155Tx = await ERC1155.connect(OWNER).mint(OWNER.address, 1, 10, "0x");
        await mintERC1155Tx.wait();
        var approveERC1155Tx = await ERC1155.connect(OWNER).setApprovalForAll(nftSwap.address, true);
        await approveERC1155Tx.wait();
        // 增发ERC20，并approve 给 NFTSwap
        var mintERC20TxO = await ERC20.connect(OWNER).mint(OWNER.address, BigNumber.from(1000000));
        await mintERC20TxO.wait();
        var approveERC20Tx = await ERC20.connect(OWNER).approve(nftSwap.address, BigNumber.from(1000000));
        await approveERC20Tx.wait();

        // 定义assets, assetType.ERC1155 = 2
        var assets = [{ Contract: ERC1155.address, TokenId: BigNumber.from(1), TokenValue: BigNumber.from(1), Type: 2 }]
        const sellTx = await nftSwap.sell(assets, 1,  "0x0000000000000000000000000000000000000000", BigNumber.from(2000000));
        await sellTx.wait();
        var receipt = await ethers.provider.getTransactionReceipt(sellTx.hash);
        expect(receipt.status).to.equal(1);
    });

    it("Should be packet sale an ERC721 token and an ERC1155 token successful", async function () {
        // 实例化 NFTSwap合约
        const NFTSwap = await ethers.getContractFactory("NFTSwap");
        const nftSwap = await upgrades.deployProxy(NFTSwap, ["0x8006C00F6217dE69f7F6630EEc377819CE68e37f", 1000000, 0, ERC20.address], { initializer: '__NFTSwap_init' });
        await nftSwap.deployed();

        // 实例化ERC721 合约
        await ERC721.deployed();

        // 增发 id=0 的token，并approve 给 NFTSwap
        var mintERC721Tx = await ERC721.connect(OWNER).mint(OWNER.address);
        await mintERC721Tx.wait();
        var approveERC721Tx = await ERC721.connect(OWNER).setApprovalForAll(nftSwap.address, true);
        await approveERC721Tx.wait();

        // 实例化ERC1155 合约
        await ERC1155.deployed();

        // 增发 id=0 的token，并approve 给 NFTSwap
        var mintERC1155Tx = await ERC1155.connect(OWNER).mint(OWNER.address, 1, 10, "0x");
        await mintERC1155Tx.wait();
        var approveERC1155Tx = await ERC1155.connect(OWNER).setApprovalForAll(nftSwap.address, true);
        await approveERC1155Tx.wait();

        // 定义assets
        var assets = [{ Contract: ERC721.address, TokenId: BigNumber.from(0), TokenValue: BigNumber.from(1), Type: 1 },
                      { Contract: ERC1155.address, TokenId: BigNumber.from(1), TokenValue: BigNumber.from(10), Type: 2 }];

        const sellTx = await nftSwap.sell(assets, 1, "0x0000000000000000000000000000000000000000", BigNumber.from(2000000));
        await sellTx.wait();

        var receipt = await ethers.provider.getTransactionReceipt(sellTx.hash);
        expect(receipt.status).to.equal(1);
    });
});
